﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;


namespace XTYAPI.通讯
{
    public delegate void ReceiveDelegateArry(byte[]receive);//1.定义一个委托
    public delegate void ReceiveDelegateString(string str);
    public  class MySocket
    {
        public event ReceiveDelegateArry ReceiveEventArry;//2.定义事件
        public event ReceiveDelegateString ReceiveEventString;
        public  MySocket(string ip, int port)
        {
            Init();
            this.IP = ip;
            this.Port = port;     
            //ClientSocket.ReceiveTimeout = 1000;
            //ClientSocket.SendTimeout=1000;
        }
        //IP地址和端口号（用于服务器端）
        private IPEndPoint ServerInfo;
        //客户端运行的Socket
        private Socket ClientSocket;
        public string IP { get; set; }
        public int Port { get; set; }
        public string LastDataStr { get; set; }
        public byte[] LastDataByte { get; set; }
        //接收缓冲区大小
        public byte[] MsgReceiveBuffer { get; set; }
        //发送缓冲区大小
        public byte[] MsgSendBuffer { get; set; }
        public bool Connected { get { return connected; } }
        private bool connected;
        byte[] reciveBuff = new byte[65535];

        private void Init()
        {
            //客户端所使用的套接字对象
            ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            MsgReceiveBuffer = new byte[65535];
            MsgSendBuffer = new byte[65535];
            //CheckForIllegalCrossThreadCalls = false;//不捕获对错误线程的调用     
        }
        //连接服务器
        public bool ConnectSocket(bool synchronous=false)
        {
            //实例化一个IP地址和端口号（用于服务器端）
            ServerInfo = new IPEndPoint(IPAddress.Parse(this.IP), Convert.ToInt32(this.Port));
            try
            {
                //通过“套接字”“根据IP地址和端口号”连接服务器
                ClientSocket.Connect(ServerInfo);
                //向服务器发送一条登录信息

                //从服务器端异步接收返回的消息（通过“ReceiveCallBack”方法异步接收消息）
                if (!synchronous)
                {
                    ClientSocket.BeginReceive(MsgReceiveBuffer, 0, MsgReceiveBuffer.Length, 0, new AsyncCallback(ReceiveCallBack), null);
                }
                connected = true;
                return true;
            }
            catch (Exception ex)
            {
                string err = ex.ToString();
                connected = false;
                return false;
               // throw new Exception("服务器联机失败" + ex.Message.ToString());
            }
        }

        //接收回发的数据
        private void ReceiveCallBack(IAsyncResult AR)
        {
            try
            {
                //结束接收（返回接收数据的大小）
                int REnd = ClientSocket.EndReceive(AR);
                //显示所接收的消息
                this.LastDataByte = MsgReceiveBuffer;             
                this.LastDataStr = Encoding.UTF8.GetString(MsgReceiveBuffer, 0, REnd);
                ReceiveEventArry?.Invoke(this.LastDataByte);//3.触发事件
                ReceiveEventString?.Invoke(this.LastDataStr);
                connected = true;
                //再次开始异步接收
                ClientSocket.BeginReceive(MsgReceiveBuffer, 0, MsgReceiveBuffer.Length, 0, new AsyncCallback(ReceiveCallBack), null);

            }
            catch(Exception ex)
            {
                //connected = false;
               // throw new Exception("已经与服务器断开连接！");
            }
        }
        //发送数据
        public bool SendDate(byte[]sendDateArry)
        {
            //获取要发送的消息
            //MsgSendBuffer = Encoding.UTF8.GetBytes(this.txtTargetClientIP.Text.Trim());
            //如果已连接则发送消息
            if (ClientSocket.Connected)
            {
                connected = true;
                //发送消息（同时异步调用“ReceiveCallBack”方法接收数据）
                ClientSocket.Send(sendDateArry);
                //ClientSocket.BeginReceive(MsgReceiveBuffer, 0, MsgReceiveBuffer.Length, 0, new AsyncCallback(ReceiveCallBack), null);
            }
            else
            {
                connected = false;              
               // throw new Exception("与服务器断开连接，无法发送消息");
            }
            return connected;
        }
        public bool SendData(string str , Encoding encoding )
        {
            try
            {
                //MsgSendBuffer = Encoding.UTF8.GetBytes(this.txtTargetClientIP.Text.Trim());
                if (ClientSocket.Connected)
                {
                    connected = true;
                    byte[] a = encoding.GetBytes(str);
                    //发送消息（同时异步调用“ReceiveCallBack”方法接收数据）
                    ClientSocket.Send(a);
                    //ClientSocket.BeginReceive(MsgReceiveBuffer, 0, MsgReceiveBuffer.Length, 0, new AsyncCallback(ReceiveCallBack), null);
                }
                else
                {
                    connected = false;
                    // throw new Exception("与服务器断开连接，无法发送消息");
                }
                return connected;
            }
            catch (Exception )
            {
                return connected;
            }  
            
        }
        public string ReciveData(Encoding en)
        {           
           int count= ClientSocket.Receive(reciveBuff);
            return en.GetString(reciveBuff,0, count);
        }

        //退出
        public void ExitSocket()
        {
            if (ClientSocket.Connected)
            {   
                ClientSocket.Shutdown(SocketShutdown.Both);
                ClientSocket.Disconnect(false);
            }
            ClientSocket.Close();
            connected = false;
        }
    }
}
